/**
 * 
 */
package com.sad.controller.action;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sad.service.IService;
import com.sad.service.ServiceManager;
import com.sad.util.G;

/**
 * 
 * @author zhaoqy
 *
 */
public abstract class BaseAction implements IAction {

	protected Logger logger = LoggerFactory.getLogger(this.getClass());

	/**
	 * Action的总入口
	 */
	public void handle(HttpServletRequest req, HttpServletResponse resp) {
		Map<String, Object> parms = new HashMap<String, Object>();
		this.setParams(req, parms);

		String action = StringUtils.defaultString(req.getParameter("action"), "pre");

		IService s = ServiceManager.allo((String) parms.get(G.K.pageid));

		if ("pre".equals(action)) {
			pre(req, resp, parms, s);
		} else if ("table".equals(action)) {
			table(req, resp, parms, s);
		} else if ("create".equals(action)) {
			create(req, resp, parms, s);
		}
	}

	/**
	 * 加载view(jsp)页面
	 * 
	 * @param req
	 * @param resp
	 * @param parms
	 */
	protected void pre(HttpServletRequest req, HttpServletResponse resp, Map<String, Object> parms,
			IService s) {

		this.beforeSetAttribute(req, parms);

		new Render().renderJsp(req, resp);
	}

	/**
	 * 渲染Table
	 * 
	 * @param req
	 * @param resp
	 * @param parms
	 */
	protected void table(HttpServletRequest req, HttpServletResponse resp,
			Map<String, Object> parms, IService s) {
		String page = StringUtils.defaultString((String) parms.get(G.K.page), "1");
		String perPage = StringUtils.defaultString((String) parms.get(G.K.perPage), "15");

		List<?> table = s.findList(parms);

		String json = "{\"result\":\"success\",\"total\":#total#,\"stats\":#datas#}";

		if (table != null && !table.isEmpty()) {
			int total = table.size();
			if (((Map) table.get(0)).get("totalcount") != null) {
				total = (Integer) ((Map) table.get(0)).get("totalcount");
				table.remove(0);
			}
			json = json.replaceAll("#total#", "" + total).replaceAll("#datas#",
					this.buildJson(pageScroll(table, page, perPage, total)));
		} else {
			json = json.replaceAll("#total#", "0").replaceAll("#datas#", "[]");
		}

		new Render().renderJson(resp, json.toString());
	}

	protected void create(HttpServletRequest req, HttpServletResponse resp,
			Map<String, Object> parms, IService s) {
		String json = s.create(parms);
		
		new Render().renderJson(resp, json);
	}

	/**
	 * 构造json
	 * 
	 * @param result
	 * @return
	 */
	protected String buildJson(List<?> result) {
		String jsonStr = "";

		try {
			ObjectMapper objectMapper = new ObjectMapper();
			jsonStr = objectMapper.writeValueAsString(result);
		} catch (IOException e) {
			logger.error(e.getMessage(), e);
		}

		return jsonStr;
	}

	/**
	 * 每个action可以Override此方法，向parms中写入参数，传递给Service层
	 * 
	 * @param req
	 * @param parms
	 */
	protected void setParams(HttpServletRequest req, Map<String, Object> parms) {
		String pageid = StringUtils.defaultString(req.getParameter(G.K.pageid), "overview");

		parms.put(G.K.pageid, pageid);

		String page = StringUtils.defaultString(req.getParameter(G.K.page), "1");
		String perPage = StringUtils.defaultString(req.getParameter(G.K.perPage), "15");
		String action = req.getParameter("action");
		
		parms.put("action", action);
		
		parms.put(G.K.page, page);
		parms.put(G.K.perPage, perPage);
	}

	/**
	 * 每个action可以@Override此方法，向JSP写入自定义数据
	 * 
	 * @param req
	 */
	protected void beforeSetAttribute(HttpServletRequest req, Map<String, Object> p) {

	}

	/**
	 * 获得jsp的文件夹名，每个action可以Override此方法，返回各自的模块名称
	 * 
	 * @return
	 */
	protected String getViewPackage() {
		return "/";
	}

	/**
	 * 内存分页
	 * 
	 * @param view
	 *            需要分页显示的数据
	 * @param page
	 *            第几页
	 * @param prePage
	 *            每页多少条
	 * @return
	 */
	protected List<?> pageScroll(List<?> view, String page, String prePage, int totalCount) {
		int prePageNum = 10;
		if (prePage != null && !"".equals(prePage)) {
			prePageNum = Integer.valueOf(prePage);
		}

		int pageNum = 0;
		if (page != null && !"".equals(page)) {
			pageNum = Integer.valueOf(page);
		}

		List<?> pageScrollList = new ArrayList();
		if (view != null && view.size() > 0) {
			// int totalCount = view.size();
			int begin = getFirst(0, pageNum, prePageNum) - 1;
			int ent = begin + prePageNum;
			// pageScrollList = view.subList(begin > 0 ? begin : 0, ent >
			// totalCount ? totalCount
			// : ent);
			pageScrollList = view;// view.subList( 0, view.size());
		}

		return pageScrollList;
	}

	protected int getFirst(int start, int pageNo, int pageSize) {
		if (start != 0)
			return start + 1;
		return ((pageNo - 1) * pageSize) + 1;
	}

	protected class Render {

		/**
		 * json方式返回数据给浏览器
		 * 
		 * @param resp
		 * @param json
		 */
		public void renderJson(HttpServletResponse resp, String json) {
			resp.setContentType("text/xml; charset=UTF-8");
			resp.setHeader("Cache-Control", "no-cache");
			resp.setHeader("Pragma", "no-cache");
			try {
				PrintWriter out = resp.getWriter();
				out.write(json);
				out.close();
			} catch (IOException e) {
				logger.error(e.getMessage(), e);
			}
		}

		/**
		 * jsp forword方式返回数据给浏览器
		 * 
		 * @param req
		 * @param resp
		 */
		public void renderJsp(HttpServletRequest req, HttpServletResponse resp) {
			try {
				req.getRequestDispatcher(
						"/pages/" + getViewPackage() + req.getParameter(G.K.pageid) + ".jsp")
						.forward(req, resp);
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			}
		}

		/**
		 * 
		 * @param req
		 * @param resp
		 * @param jspName
		 */
		public void renderUrl(HttpServletRequest req, HttpServletResponse resp, String url) {
			try {
				req.getRequestDispatcher(url).forward(req, resp);
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			}
		}
	}

}
